﻿/* ######################################## *\
 * ### Copyright (C) 2009 AJ Ravindiran ### *
\* ######################################## */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AJRavindiran.Jolt.RuneScape.Models.Items;
using AJRavindiran.Jolt.RuneScape.Models.Items.Container;

namespace AJRavindiran.Jolt.RuneScape.Models.Characters.Items
{
    /// <summary>
    /// Represents an inventory for the character.
    /// </summary>
    public class Inventory
    {
        #region Fields
        /// <summary>
        /// The size of the inventory. This is static, and should NEVER be 
        /// changed. RuneScape only allows 28 items within the inventory.
        /// </summary>
        public const int Size = 28;

        /// <summary>
        /// The container for the inventory. 
        /// Standard storage system, with 28 slots.s
        /// </summary>
        private ItemContainer container = new ItemContainer(ItemContainerType.Standard, Size);
        /// <summary>
        /// Instance of the character.
        /// </summary>
        private Character character;
        #endregion Fields

        #region Constructors
        /// <summary>
        /// Constructs a new inventory class.
        /// </summary>
        /// <param name="character">Instance of the character.</param>
        public Inventory(Character character)
        {
            this.character = character;
        }
        #endregion Constructors

        #region Methods
        /// <summary>
        /// Attempt to add an item to the player's inventory.
        /// </summary>
        /// <param name="itemId">The id of the item to add.</param>
        /// <param name="amount">Amount of the item to add.</param>
        /// <returns>Returns true if the attempt has successeded.</returns>
        public bool AddItem(int itemId, int amount)
        {
            if (itemId < 0 || itemId >= 13404)
                return false;
            bool b = container.Add(new Item(itemId, amount));
            if (!b)
            {
                RuneScape.GetPacketManager().GetFrames().SendMessage(character, "Not enough space in your inventory.");
                return false;
            }

            this.Refresh();
            return true;
        }

        /// <summary>
        /// Delete one or multiple items of the same kind.
        /// </summary>
        /// <param name="itemId">The item's id.</param>
        /// <param name="amount">Ammount to delete.</param>
        public void DeleteItem(int itemId, int amount)
        {
            this.container.Remove(new Item(itemId, amount));
            this.Refresh();
        }

        /// <summary>
        /// Delete all items of the same kind.
        /// </summary>
        /// <param name="itemId">The item's id.</param>
        public void DeleteAllItems(int itemId)
        {
            this.container.RemoveAll(new Item(itemId));
            this.Refresh();
        }

        /// <summary>
        /// Determines if the container has certain items.
        /// </summary>
        /// <param name="item">Item to look for.</param>
        /// <param name="amount">Amount to expect.</param>
        /// <returns>Returns true if the container has the items.</returns>
        public bool Contains(int item, int amount)
        {
            return this.container.Contains(new Item(item, amount));
        }

        /// <summary>
        /// Determines if the container has a certain item.
        /// </summary>
        /// <param name="item">Item to look for.</param>
        /// <returns>Returns true if the container has the item.</returns>
        public bool Contains(int item)
        {
            return this.container.ContainsOne(new Item(item));
        }

        /// <summary>
        /// Determines if the character has enough room.
        /// </summary>
        /// <param name="itemId">The item's id to check.</param>
        /// <param name="amount">Amount to expect.</param>
        /// <returns>Returns true if there is enough room.</returns>
        public bool HasRoom(int itemId, int amount)
        {
            if (RuneScape.GetItemManager().GetItemDefinition(itemId).Stackable)
                return this.container.GetAvailibleSlots() >= 1 || this.Contains(itemId);
            else
                return this.container.GetAvailibleSlots() >= amount;
        }

        /// <summary>
        /// Clear the inventory.
        /// </summary>
        public void Clear()
        {
            this.container.Clear();
            this.Refresh();
        }

        /// <summary>
        /// Represh the inventory.
        /// </summary>
        public void Refresh()
        {
            RuneScape.GetPacketManager().GetFrames()
                .SendItems(this.character, 149, 0, 93, this.container);
        }

        /// <summary>
        /// Get accessor for the inventory item container.
        /// </summary>
        /// <returns>Returns <code>this.container</code></returns>
        public ItemContainer GetContainer()
        {
            return this.container;
        }
        #endregion Methods
    }
}
